/**
*
*  目的：拿到选择合并的业务机会并展示需要选择合并的字段值，取得选取的值保存进一个新的业务机会。
*  作者：Leo
*  创建日期：2017-06-06
*
**/

public class MergeOpportunityTwoController {

    public Opportunity opp1 {get; set;}
    public Opportunity opp2 {get; set;}
    public Opportunity opp3 {get; set;}

    public List<OppBean> beanlist {get; set;}
    public boolean isShow {get; private set;}

    private String oid1;
    private String oid2;
    private String oid3;
    private Id recordTid;
    // private Id aid;
    private String accid;
    // 固定要检索的字段（就算字段集里面没有选也要检索）
    private String[] stableApis = new String[] {'Id', 'RecordTypeId', 'Probability', 'WinRatio__c', 'Name', 'Account.Name', 'AccountId', 'StageName', 'StageCanChange__c'};

    /**
     * 构造函数只负责初始化，逻辑另写方法
     */
    public MergeOpportunityTwoController () {
        beanlist = new List<OppBean>();
        isShow = false;

        oid1 = System.currentPageReference().getParameters().get('id1');
        oid2 = System.currentPageReference().getParameters().get('id2');
        oid3 = System.currentPageReference().getParameters().get('id3');
        accid = System.currentPageReference().getParameters().get('accid');
    }

    /**
     * 通过Step1页面拿到的Id，查询字段集MergeField中的对应字段值
     */
    public void init() {
        //System.debug('==========================================================================================================================');
        Set<String> idApiSet = new Set<String>();
        for (Schema.FieldSetMember sf : SObjectType.Opportunity.FieldSets.MergeField.getFields()) {
            //判断字段集中取得的字段类型如果为'REFERENCE'，则此字段值为客户ID
            if (String.valueOf(sf.getType()) == 'REFERENCE') {
                idApiSet.add(sf.getFieldPath());
            }
        }
        //System.debug('==========================================================================================================================');

        // 拼接SOQL
        String queryString = 'select';
        // 先从固定API里面找
        Set<String> stableApisSet = new Set<String>();
        for (String str : stableApis) {
            queryString += ' ' + str + ',';
            stableApisSet.add(str);
        }
        // 再从字段集里面找
        for (Schema.FieldSetMember sf : SObjectType.Opportunity.FieldSets.MergeField.getFields()) {
            // 如果字段集里面的API与固定查找API有重复，不计入SOQL文
            if (stableApisSet.contains(sf.getFieldPath())) {
                continue;
            }
            queryString += ' ' + sf.getFieldPath() + ',';
        }
        queryString = queryString.substring(0, queryString.length() - 1);
        queryString += ' from Opportunity';

        opp1 = Database.query(queryString + ' where Id = ' + '\'' + oid1 + '\'');
        opp2 = Database.query(queryString + ' where Id = ' + '\'' + oid2 + '\'');
        if (oid3 != null && oid3 != '') {
            isShow = true;
            opp3 = Database.query(queryString + ' where Id =' + '\'' + oid3 + '\'');
        }
        //拿到业务机会记录类型ID
        recordTid = opp1.RecordTypeId;

        //将字段集得到的String型id，转换为ID类型
        List<Id> idValues = new List<Id>();
        for (String str : idApiSet) {

            if (opp1.get(str) != null) idValues.add(Id.valueOf(String.valueOf(opp1.get(str))));
            if (opp2.get(str) != null) idValues.add(Id.valueOf(String.valueOf(opp2.get(str))));
            if (opp3 != null) {
                if (opp3.get(str) != null) idValues.add(Id.valueOf(String.valueOf(opp3.get(str))));
            }
        }
        // ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO, idValues));
        //通过得到的客户ID，对应拿到name
        Map<Id, Account> accMap = new  Map<Id, Account>();
        for (Account acc : [select Id, Name from Account where Id in : idValues]) {
            //ApexPag.addmessage(new ApexPages.message(ApexPages.severity.INFO, acc.Id + ':'+acc.Name));
            accMap.put(acc.Id, acc);
        }
        //system.debug('xxxxxxxxxxxx:'+accMap);
        for (Schema.FieldSetMember sf : SObjectType.Opportunity.FieldSets.MergeField.getFields()) {
            beanlist.add(new OppBean(sf, opp1, opp2, opp3, accMap));
        }
        //System.debug('==========================================================================================================================');
    }

    //将checkbox、字段值、字段名封装
    public class OppBean {

        public String fieldname {get; set;}
        public String fieldApi {get; set;}
        public String fieldType {get; set;}

        public String fieldId1 {get; set;}
        public String fieldId2 {get; set;}
        public String fieldId3 {get; set;}

        public String fieldVal1 {get; set;}
        public String fieldVal2 {get; set;}
        public String fieldVal3 {get; set;}

        public Boolean chk1 {get; set;}
        public Boolean chk2 {get; set;}
        public Boolean chk3 {get; set;}

        public OppBean(FieldSetMember fsm, Opportunity opp1, Opportunity opp2, Opportunity opp3, Map<Id, Account> accMap) {

            fieldname = fsm.getLabel();
            fieldApi = fsm.getFieldPath();
            fieldType = String.valueOf(fsm.getType());

            // 非ID字段
            fieldId1 = null;
            fieldId2 = null;
            fieldId3 = null;
            fieldVal1 = String.valueOf(opp1.get(fsm.getFieldPath()));
            fieldVal2 = String.valueOf(opp2.get(fsm.getFieldPath()));
            if (opp3 != null) fieldVal3 = String.valueOf(opp3.get(fsm.getFieldPath()));
            
            // 查找字段页面显示name
            if (fieldType == 'REFERENCE') {
                fieldId1 = String.valueOf(opp1.get(fsm.getFieldPath()));
                fieldId2 = String.valueOf(opp2.get(fsm.getFieldPath()));

                if (String.isBlank(fieldId1) == false && accMap.containsKey(Id.valueOf(fieldId1))) fieldVal1 = accMap.get(Id.valueOf(fieldId1)).Name;
                
                if (String.isBlank(fieldId2) == false && accMap.containsKey(Id.valueOf(fieldId2))) fieldVal2 = accMap.get(Id.valueOf(fieldId2)).Name;
                
                if (opp3 != null) {
                    fieldId3 = String.valueOf(opp3.get(fsm.getFieldPath()));
                    if (String.isBlank(fieldId3) == false && accMap.containsKey(Id.valueOf(fieldId3))) fieldVal3 = accMap.get(Id.valueOf(fieldId3)).Name;
                    
                }
            }
            if (fieldType == 'Date') {
                Date d1 = Date.valueOf(opp1.get(fsm.getFieldPath()));
                Date d2 = Date.valueOf(opp2.get(fsm.getFieldPath()));
                Date d3 = Date.valueOf(opp2.get(fsm.getFieldPath()));
                fieldVal1 =  d1 ==null ? null : d1.format();
                fieldVal2 = d2 == null ? null : d2.format();
                if (opp3 != null) {
                    fieldVal3 = d3== null ? null : d3.format();
                }


            }
            chk1 = false;
            chk2 = false;
            chk3 = false;
        }
    }

    private void setFieldValue(OppBean ob , Opportunity newOpp ){
        if ( ob.fieldType != 'REFERENCE' ) {
            if (ob.fieldType == 'DATE') {
                Date dat = ob.fieldVal1 == null ? null : Date.valueOf(ob.fieldVal1);
                newOpp.put(ob.fieldApi, dat);
            } else if (ob.fieldType == 'Boolean') {
                Boolean is = Boolean.valueOf(ob.fieldVal1);
                newOpp.put(ob.fieldApi, is);
            } else {
                newOpp.put(ob.fieldApi, ob.fieldVal1);
            }
        } else {
            newOpp.put(ob.fieldApi, ob.fieldid1);
        }
    }
    /**
     * 获取选取字段值，新建一个业务机会并跳转到新业务机会的页面
     */
    public PageReference save1() {
        System.debug('==========================================================================================================================');

        Savepoint sp = Database.setSavepoint();
        System.debug('==========================================================================================================================');
        try {
            System.debug('==========================================================================================================================');
            Opportunity newOpp = new Opportunity();
            List<String> apis = new List<String>();

            for (OppBean ob : beanlist) {
                if (ob.chk1 == true) setFieldValue(ob,newOpp);
                if (ob.chk2 == true) setFieldValue(ob,newOpp);
                if (ob.chk3 == true) setFieldValue(ob,newOpp);
            }
            // 记录类型和客户名固定
            newOpp.RecordTypeId = recordTid;
            newOpp.AccountId = accid;

            //阶段取几个业务机会中最新(阶段最后面那个阶段)，赢单率取那个阶段的赢单率（前面阶段的赢单率可以默认为最新阶段的业务机会的赢单率）
            String stageName = '';
            String stageCanChange = '';
            Decimal winRatio;
            System.debug('==========================================================================================================================');
            
             stageName = opp1.StageName;
             stageCanChange = opp1.StageCanChange__c;
             if(opp2.Probability >= opp1.Probability) stageName = opp2.StageName;
             if(opp2.Probability >= opp1.Probability) stageCanChange = opp2.StageCanChange__c;
             if(opp3 != null && opp3.Probability >= opp2.Probability) stageName = opp3.StageName;
             if(opp3 != null && opp3.Probability >= opp2.Probability) stageCanChange = opp3.StageCanChange__c;
            /*if (opp3 != null ) {
                if (opp1.Probability >= opp2.Probability && opp1.Probability >= opp3.Probability) {
                    stageName = opp1.StageName;
                    stageCanChange = opp1.StageCanChange__c;
                }
                if (opp2.Probability >= opp1.Probability && opp2.Probability >= opp3.Probability) {
                    stageName = opp2.StageName;
                    stageCanChange = opp2.StageCanChange__c;
                }
                if (opp3.Probability >= opp1.Probability && opp3.Probability >= opp2.Probability) {
                    stageName = opp3.StageName;
                    stageCanChange = opp3.StageCanChange__c;
                }
            } else {
                stageName = opp1.Probability > opp2.Probability ? opp1.StageName : opp2.StageName;
                stageCanChange = opp1.Probability > opp2.Probability ? opp1.StageCanChange__c : opp2.StageCanChange__c;
            }*/

            //合并的业务机会赢单率继承最大的
                winRatio = opp1.WinRatio__c ; 
                if(opp2.WinRatio__c >= winRatio ) winRatio = opp2.WinRatio__c;
                if(opp3 != null && opp3.WinRatio__c >= winRatio ) winRatio = opp3.WinRatio__c;
            /*if (opp3 != null ) {


                // if (opp1.WinRatio__c >= opp2.WinRatio__c && opp1.WinRatio__c >= opp3.WinRatio__c) {
                //     winRatio = opp1.WinRatio__c;
                // }
                // if (opp2.WinRatio__c >= opp1.WinRatio__c && opp2.WinRatio__c >= opp3.WinRatio__c) {
                //     winRatio = opp2.WinRatio__c;
                // }
                // if (opp3.WinRatio__c >= opp1.WinRatio__c && opp3.WinRatio__c >= opp2.WinRatio__c) {
                //     winRatio = opp3.WinRatio__c;
                // }
                System.debug(opp1.WinRatio__c + '=============++' + opp2.WinRatio__c);
            } else {
                winRatio = opp1.WinRatio__c > opp2.WinRatio__c ? opp1.WinRatio__c : opp2.WinRatio__c;
                System.debug(opp1.WinRatio__c + '=============++' + opp2.WinRatio__c);
            }*/

            // 用来回避一些验证规则的check
            newOpp.Is_merged__c = true;
            // 结束时间固定为一年后
            newOpp.CloseDate = Date.today().addDays(365);
            // 项目类型自动计算
            // newOpp.ProjectType__c = '';
            newOpp.Name = '1 ';
            //清空有效报价、有效报价(试剂)、有效测算(试剂)
            newOpp.ActiveQuote__c = null;
            newOpp.ActiveQuoteReagent__c = null;
            newOpp.ActiveMeasureReagent__c = null;


            // 先把业务机会的阶段设为意向，追加了意向产品之后再把阶段设为实际的阶段
            // 为了绕过“必须包含意向产品”的check
            newOpp.StageName = '意向';
            newOpp.WinRatio__c = winRatio;

            if (String.isBlank(newOpp.NewName__c) == true) {
                ApexPages.addMessage(new ApexPages.Message (ApexPages.Severity.ERROR, '\'' + '业务机会标注' + '\'' + '必须选取一个'));
                return null;
            } else {
                newOpp.NewName__c += '(合并)';
            }
            insert newOpp;
            System.debug(newOpp.WinRatio__c + '+++++++++++++++++++++++++++++++++++');

            //将旧业务机会下的意向产品关联到新业务机会下
            Set<Id> oppids = new Set<Id>();
            Map<String, String> ipMap = new  Map<String, String>();
            oppids.add(opp1.Id);
            oppids.add(opp2.Id);
            if (opp3 != null) {
                oppids.add(opp3.Id);
            }
            //克隆意向产品方法2：配列克隆
            List<IntentProduct__c> oldips = [ select Name, Opportunity__c, Product__c from IntentProduct__c where Opportunity__c in :oppids ];

            List<IntentProduct__c> newips = oldips.deepclone(false, true);
            for ( IntentProduct__c ip : newips) {
                if (ipMap.containsKey(ip.Product__c)) {
                    continue;
                } else {
                    ipMap.put(ip.Product__c, ip.Product__c);
                    ip.Opportunity__c = newOpp.Id;
                }
            }
            insert newips;

            // 把阶段更新为实际的阶段
            newOpp.StageName = stageName;
            newOpp.StageCanChange__c = stageCanChange;

            update newOpp;

            //克隆赢单率小组到新业务机会
            String sname = '';
            Map<String, String> wrtMap = new  Map<String, String>();
           /* if ( opp3 != null ) {
                if (opp1.Probability == opp2.Probability && opp2.Probability == opp3.Probability) {
                    if (opp1.WinRatio__c >= opp2.WinRatio__c && opp1.WinRatio__c >= opp3.WinRatio__c) {
                        cloneWin(opp1.Id, newOpp);
                    }
                    if (opp2.WinRatio__c >= opp1.WinRatio__c && opp2.WinRatio__c >= opp3.WinRatio__c) {
                        cloneWin(opp2.Id, newOpp);
                    }
                    if (opp3.WinRatio__c >= opp1.WinRatio__c && opp3.WinRatio__c >= opp2.WinRatio__c) {
                        cloneWin(opp3.Id, newOpp);
                    }
                }
                if ( opp1.Probability > opp2.Probability && opp1.Probability > opp3.Probability ) {
                    cloneWin(opp1.Id, newOpp);
                }
                if ( opp2.Probability > opp1.Probability && opp2.Probability > opp3.Probability ) {
                    cloneWin(opp2.Id, newOpp);
                }
                if ( opp3.Probability > opp1.Probability && opp3.Probability > opp2.Probability ) {
                    cloneWin(opp3.Id, newOpp);
                }
            } else {
                if (opp1.Probability > opp2.Probability) {
                    cloneWin(opp1.Id, newOpp);
                }
                if (opp1.Probability < opp2.Probability) {
                    cloneWin(opp2.Id, newOpp);
                }
                if (opp1.Probability == opp2.Probability) {
                    if ( opp1.WinRatio__c >= opp2.WinRatio__c ) {
                        cloneWin(opp1.Id, newOpp);
                    }
                    if ( opp1.WinRatio__c < opp2.WinRatio__c ) {
                        cloneWin(opp2.Id, newOpp);
                    }
                }
            }
            */

            //修改选择合并的业务机会的状态(被合并业务机会中止，并关联到新业务及机会上)
            List<Opportunity> uopplist = new List<Opportunity>();
            List<User> userList = [ SELECT ID, LastName FROM User WHERE LastName = '杨雪舒' ];

            opp1.Is_Stop__c = true;
            opp1.SucceedOpportunity__c = newOpp.Id;
            opp1.NewName__c += '(已被合并)';
            if ( userList != null ) {
                opp1.OwnerId = userList[0].Id;
            }
            uopplist.add(opp1);
            opp2.Is_Stop__c = true;
            opp2.SucceedOpportunity__c = newOpp.Id;
            opp2.NewName__c += '(已被合并)';
            if ( userList != null ) {
                opp2.OwnerId = userList[0].Id;
            }
            uopplist.add(opp2);
            if ( opp3 != null ) {
                opp3.Is_Stop__c = true;
                opp3.SucceedOpportunity__c = newOpp.Id;
                opp3.NewName__c += '(已被合并)';
                if ( userList != null ) {
                    opp3.OwnerId = userList[0].Id;
                }
                uopplist.add(opp3);
            }
            update uopplist;
            return new PageReference('/' + newOpp.Id);
        } catch (Exception e) {
            // 回滚
            Database.rollback(sp);
            ApexPages.addMessage(new ApexPages.Message (ApexPages.Severity.ERROR,
                                 '操作出错：' + e.getMessage()+e.getStackTraceString()));
        }
        return null;
    }

    /**
     * 回到Step1画面
     */
    public PageReference cancel() {
        System.debug('==============================');
        return new PageReference('/apex/MergeOpportunities?accid=' + accid);
    }

    /*public void cloneWin( Id oppid, Opportunity opp ) {

        List<StageWinRate__c> swrList = [ SELECT Id, (SELECT Id, Opportunity__c, StageWinRate__c, WinRadio__c, SupportRatio__c, Post__c, Weight__c, Contact__r.Name FROM StageWinRadio__r)
                                          FROM StageWinRate__c WHERE Opportunity__c = : oppid Order By CreatedDate DESC limit 1 ];
        List<WinRatioTeam__c> wrtList = new List<WinRatioTeam__c>();
        for ( WinRatioTeam__c swr : swrList[0].StageWinRadio__r) {
            wrtList.add(swr);
        }
        StageWinRate__c newo = [ select Id, Opportunity__c, Name from StageWinRate__c where Opportunity__c = :opp.Id Order By CreatedDate DESC limit 1];
        List<WinRatioTeam__c> newWrtList = wrtList.deepClone(false, true);
        for ( WinRatioTeam__c wrt : newWrtList ) {
            wrt.StageWinRate__c = newo.Id;
            wrt.Opportunity__c = opp.Id;
            wrt.Name = wrt.Contact__r.Name;
        }
        insert newWrtList;
    }*/
}